
import screenlets
import gobject
import threading
import twitter
import urllib
import gtk

import traceback

class UserInfo:
    def __init__ (self, name=None, screen_name=None, iconPixbuf=None):
        self.name = name
        self.screen_name = screen_name
        self.iconPixbuf = iconPixbuf

class Timeline:
    statuses = []
    users = {}

    def __init__ (self, statuses=None, users=None):
        if statuses: self.statuses = list(statuses)
        if users: self.users = dict(users)
            
class TwitterResult:
    SUCCESS		= 1
    ERROR		= 2

class TwitterUpdateMethod:
    PUBLIC = 1
    FRIENDS = 2

class TwitterBackend (gobject.GObject):
    """The backend class which performs getting Twitter statuses"""

    statuses = []
    users = {}
    icon_cache = {}
    handler_ids = []

    __api = None

    started = False

    __lock = threading.Lock()

    def __init__ (self, screenlet, update_method):
        print "TwitterBackend.__init__"
        gobject.GObject.__init__(self)
        # properties
        self.screenlet		= screenlet		# assigned TwitterScreenlet
        self.getting		= False			# not getting yet
        self.error					= ''		# human-readable error message
        self.options		= []				# ???additonal ptions for backend
        self.update_method      = update_method

        user_name,password = self.screenlet.account
        self.__api = self.get_twitter_api(user_name, password)

        if self.update_method == TwitterUpdateMethod.FRIENDS:
            self.__update_method = self.__api.GetFriendsTimeline
        else:
            self.__update_method = self.__api.GetPublicTimeline

    def get_twitter_api(self, user_name = None, password= None):
        if user_name == '' :
            user_name = None
            password = None
        api = twitter.Api(user_name, password)

        # Mail to Alex...
        api.SetUserAgent('TwitterScreenlet')
        
        #api.SetCacheTimeout(0)
        return api

    def get_timeline_start(self):
        if self.getting: return        
        threading.Thread(target=self.__get).start()

    def post_message_start(self, text):
        threading.Thread(target=self.__post, args=(text,)).start()

    def __get (self):
        """ """
        self.getting = True
        result = TwitterResult.SUCCESS
        try:
            self.__get_timeline()
        except:
            result = TwitterResult.ERROR

        gobject.idle_add(self.screenlet.on_get_timeline, Timeline(self.statuses, self.users), result)
        self.getting = False

    def __post (self, text):
        """ post message to server"""
        try:
            self.__lock.acquire()
            self.__api.PostUpdate(text)
        finally:
            self.__lock.release()    
    
    def __get_timeline(self):
        """ get twitter timeline data"""
        try:
            self.__lock.acquire()
            self.statuses = self.__update_method()
        finally:
            self.__lock.release()    

        new_icon_cache = {}
        user_dict = {}

        for status in self.statuses:
            if not user_dict.has_key(status.GetUser().GetId()):

                user_name = status.GetUser().GetName()
                screen_name = status.GetUser().GetScreenName()

                # get Profile Image
                try:
                    icon_url = status.GetUser().GetProfileImageUrl()
                    if self.icon_cache.has_key(icon_url):
                        icon_pixbuf = icon_cache[icon_url]
                    elif new_icon_cache.has_key(icon_url):
                        icon_pixbuf = new_icon_cache[icon_url]
                    else:
                        icon_path, headers = urllib.urlretrieve(urllib.quote(icon_url.encode("utf-8"), ':/'))
                        icon_pixbuf = gtk.gdk.pixbuf_new_from_file(icon_path)

                    new_icon_cache[icon_url] = icon_pixbuf
                except:
                    traceback.print_exc()
                    print 'Failed to Get icon pixbuf.'
                    print icon_url
                    icon_pixbuf = None
                user_dict[status.GetUser().GetId()] = UserInfo(user_name, screen_name, icon_pixbuf)

        self.users = user_dict
        icon_cache = new_icon_cache
        urllib.urlcleanup()

    def set_update_method(self, update_method):
        self.__lock.acquire()
        if update_method == TwitterUpdateMethod.FRIENDS:
            self.__update_method = self.__api.GetFriendsTimeline
        else:
            self.__update_method = self.__api.GetPublicTimeline
        self.__lock.release()
